import { applyDecorators } from '@nestjs/common';
import { ApiResponse, getSchemaPath } from '@nestjs/swagger';
import { Decorator_ApiOperatione_Base } from '../decorators/apiOperatione';

type IUtil_ApiResponse_Arguements_DataType =
  | 'dataType_ell'
  | 'dataType_delete'
  | 'dataType_update'
  | 'dataType_add'
  | 'dataType_list'
  | 'dataType_string'
  | 'dataType_number'
  | 'dataType_object'
  | 'dataType_array'
  | 'dataType_listSelect';
type IUtil_ApiResponse_Arguements = {
  dataType: IUtil_ApiResponse_Arguements_DataType;
  //apiKey: string;
  status?: number;
  description?: string;
  type?: any;
  summary?: string;
  noAuth?: boolean;
};
/**
 * @description 自定义装饰器，使用此装饰器可以为 API 方法添加标准的 Swagger 响应类型，并控制是否需要 JWT 验证。
 * @example
 * @util_ApiResponse_Base(
 *   'string',
 *   {
 *     status: 201,
 *     description: 'example',
 *     type: 'example',
 *     //apiKey: 'example Post',
 *     summary: 'example',
 *   },
 *   true,
 * )
 * @param {IUtil_ApiResponse_Arguements} options - API 响应的可选设置。
 * @param {IUtil_ApiResponse_Arguements_DataType} option.dataType - 返回的数据类型。
 * @param {string} options.//apiKey - 用于认证的 API 键值。
 * @param {number} [options.status] - 响应的 HTTP 状态码。
 * @param {string} [options.description] - 响应的描述。
 * @param {any} [options.type] - 响应数据的类型。
 * @param {string} [options.summary] - 响应的摘要。
 * @param {boolean} [options.noAuth=false] - 是否需要认证。
 * @returns {ReturnType<typeof applyDecorators>} - 返回应用的装饰器。
 */
export function util_ApiResponse_Base(
  options: IUtil_ApiResponse_Arguements,
): ReturnType<typeof applyDecorators> {
  const dataTypeObj = {
    dataType_array: {
      status: 200,
      description: '查询成功',
      summary: '查询列表',
      schema: {
        type: 'array',
        items: options.type ? { $ref: getSchemaPath(options.type) } : { type: 'string', example: '略' },
      },
    },
    dataType_object: {
      status: 200,
      description: '操作成功',
      summary: '操作',
      schema: { $ref: getSchemaPath(options.type) },
    },
    dataType_number: {
      status: 200,
      description: '操作成功',
      summary: '操作',
      schema: { type: 'number', example: 0 },
    },
    dataType_string: {
      status: 200,
      description: '操作成功',
      summary: '操作',
      schema: { type: 'string', example: options.type ? options.type : '略' },
    },
    dataType_list: {
      status: 200,
      description: '查询成功',
      summary: '查询列表',
      schema: {
        type: 'object',
        properties: {
          totalElements: { type: 'number', example: 1 },
          list: {
            type: 'array',
            items: options.type
              ? { $ref: getSchemaPath(options.type) }
              : { type: 'string', example: '略' },
          },
        },
      },
    },
    dataType_add: {
      status: 201,
      description: '新增成功',
      summary: '新增',
      schema: options.type
        ? { type: 'object', $ref: getSchemaPath(options.type) }
        : { type: 'string', example: '略' },
    },
    dataType_update: {
      status: 200,
      description: '修改成功',
      summary: '修改',
      schema: options.type
        ? { type: 'object', $ref: getSchemaPath(options.type) }
        : { type: 'string', example: '修改成功' },
    },
    dataType_delete: {
      status: 200,
      description: '删除成功',
      summary: '删除',
      schema: { type: 'string', example: '删除成功' },
    },
    dataType_listSelect: {
      status: 200,
      description: '查询成功',
      summary: '查询全部列表',
      schema: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            id: {
              type: 'number',
              description: '对象的唯一标识',
            },
            name: {
              type: 'string',
              description: '需要展示的内容',
            },
          },
        },
      },
    },
    dataType_ell: {
      status: 200,
      description: '操作成功',
      summary: '操作',
      schema: { type: 'string', example: '略' },
    },
  };
  const status = options?.status || dataTypeObj[options.dataType].status;
  const description = options?.description || dataTypeObj[options.dataType].description;
  return applyDecorators(
    ApiResponse({
      status,
      description,
      schema: {
        type: 'object',
        properties: {
          data: dataTypeObj[options.dataType].schema,
          statusCode: { type: 'string', example: status },
        },
      },
    }),
    Decorator_ApiOperatione_Base(
      { summary: options?.summary || dataTypeObj[options.dataType].summary },
      options.noAuth,
    ),
  );
}
